<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">

  <link href="../dist/jsoneditor.css" rel="stylesheet" type="text/css">
  <script src="../dist/jsoneditor.js"></script>

  <style type="text/css">
    body {
      font: 10.5pt arial;
      color: #4d4d4d;
      line-height: 150%;
      width: 100%;
      padding-left: 10px;
    }

    code {
      background-color: #f5f5f5;
    }

    #containerLeft {
      display: inline-block;
      width: 500px;
      height: 500px;
      margin-right: 10px;
    }

    #containerRight {
      display: inline-block;
      width: 500px;
      height: 500px;
    }
    #containerRight .different_element {
      background-color: greenyellow  !important;
    }
    #containerLeft .different_element {
      background-color: violet  !important;
    }
    </style>
</head>
<body>

<h3>JSON Diff</h3>
<p>
  This example highlights the differences between two JSON objects using the option <code>onClassName</code>.
  Make a change in the left or right editor to see the changes update accordingly.
</p>
<div id="wrapper">
  <div id="containerLeft"></div>
  <div id="containerRight"></div>
</div>

<script>
  var containerLeft = document.getElementById('containerLeft');
  var containerRight = document.getElementById('containerRight');

  function findNodeInJson(json, path){
    if(!json || path.length ===0) {
      return {field: undefined, value: undefined}
    }    
    var first = path[0];
    var remainingPath = path.slice(1);

    if(remainingPath.length === 0) {
      return {field: (typeof json[first] !== 'undefined' ? first : undefined), value: json[first]};
    } else {
      return findNodeInJson(json[first], remainingPath)
    }
  }

  function onClassName({ path, field, value }) {
    var thisNode = findNodeInJson(jsonRight, path);
    var oppositeNode = findNodeInJson(jsonLeft, path);
    var isValueEqual = JSON.stringify(thisNode.value) === JSON.stringify(oppositeNode.value);

    if(Array.isArray(thisNode.value) && Array.isArray(oppositeNode.value)) {
      isValueEqual = thisNode.value.every(function (e) {
        return oppositeNode.value.includes(e);
      })
    }

    if (thisNode.field === oppositeNode.field && isValueEqual) {
      return 'the_same_element';
    } else {
      return 'different_element'
    }
  }

  var optionsLeft = {
    mode: 'tree',
    onError: function (err) {
      alert(err.toString());
    },
    onClassName: onClassName,
    onChangeJSON: function (j) {
      jsonLeft = j;      
      window.editorRight.refresh()
    }    
  };
  
  var optionsRight = {
    mode: 'tree',
    onError: function (err) {
      alert(err.toString());
    },
    onClassName: onClassName,
    onChangeJSON: function (j) {
      jsonRight = j;
      window.editorLeft.refresh();
    }    
  };

  var jsonLeft = {
    "arrayOfArrays": [1, 2, 999, [3,4,5]],
    "someField": true,
    "boolean": true,
    "htmlcode": '&quot;',
    "escaped_unicode": '\\u20b9',
    "unicode": '\u20b9,\uD83D\uDCA9',
    "return": '\n',
    "null": null,
    "thisObjectDoesntExistOnTheRight" : {key: "value"},
    "number": 123,
    "object": {"a": "b","new":4, "c": "d", "e": [1, 2, 3]},
    "string": "Hello World",
    "url": "http://jsoneditoronline.org",
    "[0]": "zero"
  };

  var jsonRight = {
    "arrayOfArrays": [1, 2, [3,4,5]],
    "boolean": true,
    "htmlcode": '&quot;',
    "escaped_unicode": '\\u20b9',
    "thisFieldDoesntExistOnTheLeft": 'foobar',
    "unicode": '\u20b9,\uD83D\uDCA9',
    "return": '\n',
    "null": null,
    "number": 123,
    "object": {"a": "b",  "c": "d", "e": [1, 2, 3]},
    "string": "Hello World",
    "url": "http://jsoneditoronline.org",
    "[0]": "zero"
  };
  
  window.editorLeft = new JSONEditor(containerLeft, optionsLeft, jsonLeft);
  window.editorRight = new JSONEditor(containerRight, optionsRight, jsonRight);
</script>
</body>
</html>
